/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package xcore.model.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.InternalEList;

import xcore.model.ModelPackage;
import xcore.model.XClass;
import xcore.model.XRefFeature;
import xcore.model.XReference;
import xcore.model.XRelation;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>XReference</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link xcore.model.impl.XReferenceImpl#getXClass <em>XClass</em>}</li>
 *   <li>{@link xcore.model.impl.XReferenceImpl#getXRelations <em>XRelations</em>}</li>
 *   <li>{@link xcore.model.impl.XReferenceImpl#getFeatures <em>Features</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class XReferenceImpl extends XFeatureImpl implements XReference {
	/**
	 * The cached value of the '{@link #getXClass() <em>XClass</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getXClass()
	 * @generated
	 * @ordered
	 */
	protected XClass xClass;

	/**
	 * The cached value of the '{@link #getXRelations() <em>XRelations</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getXRelations()
	 * @generated
	 * @ordered
	 */
	protected EList<XRelation> xRelations;

	/**
	 * The cached value of the '{@link #getFeatures() <em>Features</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFeatures()
	 * @generated
	 * @ordered
	 */
	protected EList<XRefFeature> features;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected XReferenceImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ModelPackage.Literals.XREFERENCE;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public XClass getXClass() {
		if (xClass != null && xClass.eIsProxy()) {
			InternalEObject oldXClass = (InternalEObject)xClass;
			xClass = (XClass)eResolveProxy(oldXClass);
			if (xClass != oldXClass) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ModelPackage.XREFERENCE__XCLASS, oldXClass, xClass));
			}
		}
		return xClass;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public XClass basicGetXClass() {
		return xClass;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetXClass(XClass newXClass, NotificationChain msgs) {
		XClass oldXClass = xClass;
		xClass = newXClass;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.XREFERENCE__XCLASS, oldXClass, newXClass);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setXClass(XClass newXClass) {
		if (newXClass != xClass) {
			NotificationChain msgs = null;
			if (xClass != null)
				msgs = ((InternalEObject)xClass).eInverseRemove(this, ModelPackage.XCLASS__XREFERENCES, XClass.class, msgs);
			if (newXClass != null)
				msgs = ((InternalEObject)newXClass).eInverseAdd(this, ModelPackage.XCLASS__XREFERENCES, XClass.class, msgs);
			msgs = basicSetXClass(newXClass, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.XREFERENCE__XCLASS, newXClass, newXClass));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<XRelation> getXRelations() {
		if (xRelations == null) {
			xRelations = new EObjectContainmentWithInverseEList<XRelation>(XRelation.class, this, ModelPackage.XREFERENCE__XRELATIONS, ModelPackage.XRELATION__XREFERENCE);
		}
		return xRelations;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<XRefFeature> getFeatures() {
		if (features == null) {
			features = new EObjectContainmentWithInverseEList<XRefFeature>(XRefFeature.class, this, ModelPackage.XREFERENCE__FEATURES, ModelPackage.XREF_FEATURE__XREFERENCE);
		}
		return features;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ModelPackage.XREFERENCE__XCLASS:
				if (xClass != null)
					msgs = ((InternalEObject)xClass).eInverseRemove(this, ModelPackage.XCLASS__XREFERENCES, XClass.class, msgs);
				return basicSetXClass((XClass)otherEnd, msgs);
			case ModelPackage.XREFERENCE__XRELATIONS:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getXRelations()).basicAdd(otherEnd, msgs);
			case ModelPackage.XREFERENCE__FEATURES:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getFeatures()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ModelPackage.XREFERENCE__XCLASS:
				return basicSetXClass(null, msgs);
			case ModelPackage.XREFERENCE__XRELATIONS:
				return ((InternalEList<?>)getXRelations()).basicRemove(otherEnd, msgs);
			case ModelPackage.XREFERENCE__FEATURES:
				return ((InternalEList<?>)getFeatures()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ModelPackage.XREFERENCE__XCLASS:
				if (resolve) return getXClass();
				return basicGetXClass();
			case ModelPackage.XREFERENCE__XRELATIONS:
				return getXRelations();
			case ModelPackage.XREFERENCE__FEATURES:
				return getFeatures();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ModelPackage.XREFERENCE__XCLASS:
				setXClass((XClass)newValue);
				return;
			case ModelPackage.XREFERENCE__XRELATIONS:
				getXRelations().clear();
				getXRelations().addAll((Collection<? extends XRelation>)newValue);
				return;
			case ModelPackage.XREFERENCE__FEATURES:
				getFeatures().clear();
				getFeatures().addAll((Collection<? extends XRefFeature>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ModelPackage.XREFERENCE__XCLASS:
				setXClass((XClass)null);
				return;
			case ModelPackage.XREFERENCE__XRELATIONS:
				getXRelations().clear();
				return;
			case ModelPackage.XREFERENCE__FEATURES:
				getFeatures().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ModelPackage.XREFERENCE__XCLASS:
				return xClass != null;
			case ModelPackage.XREFERENCE__XRELATIONS:
				return xRelations != null && !xRelations.isEmpty();
			case ModelPackage.XREFERENCE__FEATURES:
				return features != null && !features.isEmpty();
		}
		return super.eIsSet(featureID);
	}

} //XReferenceImpl
